package servidor;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

import requisicao.ObservadorRequisicao;
import requisicao.Requisicao;

public class Servidor implements Runnable, Observado, ObservadorRequisicao {

	private int porta;
	private ServerSocket serverSocket = null;
	private boolean ativo;
	private List<ObservadorServidor> observadores = new ArrayList<ObservadorServidor>();
	
	public Servidor(int porta){
		this.porta = porta;
	}
	
	@Override
	public void run() {
		inicializar();
		while(ativo){
			receberConexoes();
		}
		finalizar();
		
	}

	private void finalizar() {
		try {
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		notificarObservadores();
	}

	private void inicializar() {
		try {
			serverSocket = new ServerSocket(porta);
			ativo = true;
			notificarObservadores();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	private void receberConexoes() {		
		try {
			serverSocket.setSoTimeout(100);
			Requisicao req = new Requisicao(serverSocket.accept());			
			new Thread(req).start();
			
		} catch (SocketException e) {	
		} catch (IOException e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
		}
	}

	@Override
	public void addObservador(ObservadorServidor observador) {
		observadores.add(observador);		
	}

	@Override
	public void remObservador(ObservadorServidor observador) {
		observadores.remove(observador);
		
	}

	@Override
	public void notificarObservadores() {
		for (ObservadorServidor observador : observadores) {
			observador.servidorAtualizado(this);
		}		
	}

	public boolean isAtivo() {
		return ativo;
	}

	public void setAtivo(boolean ativo){
		this.ativo = ativo;
	}

	public int getPorta() {
		return porta;
	}
	@Override
	public void requisicaoAtualizada(Requisicao requisicao) {
		notificarObservadores();
	}

}
